<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Cache-Control" content="no-siteapp">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=1, minimum-scale=1, maximum-scale=1">
<meta name="renderer" content="webkit">
<meta name="google" value="notranslate">
<meta name="robots" content="index,follow">


<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Akkuman">
<meta name="twitter:description" content="Akkuman的技术博客">
<meta name="twitter:image:src" content="http://127.0.0.1:8000/images/avatar.png">

<meta property="og:url" content="http://127.0.0.1:8000">
<meta property="og:title" content="Akkuman">
<meta property="og:description" content="Akkuman的技术博客">
<meta property="og:site_name" content="Akkuman">
<meta property="og:image" content="http://127.0.0.1:8000/images/avatar.png">
<meta property="og:type" content="website">
<meta name="robots" content="noodp">

<meta itemprop="name" content="Akkuman">
<meta itemprop="description" content="Akkuman的技术博客">
<meta itemprop="image" content="http://127.0.0.1:8000/images/avatar.png">

<link rel="canonical" href="http://127.0.0.1:8000">

<link rel="shortcut icon" href="/favicon.png">
<link rel="apple-itouch-icon" href="/favicon.png">

<link type="text/css" rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="/bundle/css/prism.css">
<link type="text/css" rel="stylesheet" href="/bundle/css/zoom.css">
<link type="text/css" rel="stylesheet" href="/bundle/css/main.css">
<script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>



<script>var cPlayers = [];var cPlayerOptions = [];</script>


<script type="text/javascript">
    var timeSinceLang = {
        year: '年前',
        month: '个月前',
        day: '天前',
        hour: '小时前',
        minute: '分钟前',
        second: '秒前'
    };
    var root = '';
</script>


        <meta name="keywords" content="CrackMe,逆向,">
        <meta name="description" content="160CrackMe第十九Brad Soblesky.2">
        <meta name="author" content="Akkuman">
        <title>160CrackMe第十九Brad Soblesky.2</title>
    </head>
    <body>
        
        <header id="header" class="clearfix">
  <div class="container-fluid">
      <div class="row">
          <div class="logo">
              <div class="header-logo">
                <script>
                  var getwbclass = function() {
                    var wbclass = ['b', 'w'];
                    return wbclass[Math.floor(Math.random()*wbclass.length)];
                  }
                  var sitetitle = "Akkuman";
                  for (i in sitetitle) {
                    document.write('<a href="/"><span class="' + getwbclass() + ' titlechar">' + sitetitle.charAt(i) + '</span></a>');
                  }          
                  
                </script>
                
                <a id="btn-menu" href="javascript:isMenu();">
                    <span class="b">·</span>
                </a>
                <a href="javascript:isMenu1();">
                    <span id="menu-1" class="bf">1</span>
                </a>
                <a href="javascript:isMenu2();">
                    <span id="menu-2" class="bf">2</span>
                </a>
                <a href="javascript:isMenu3();">
                    <span id="menu-3" class="bf">3</span>
                </a>
              </div>
              <div id="menu-page">
                <a href="/archive.html"><li>归档</li></a>
                <a href="/tag.html"><li>标签</li></a>
                
                <a href="/atom.xml"><li>订阅</li></a>
                
                <a href="about.html"><li>关于</li></a>
              </div>
              <div id="search-box">
                  <div id="search">
                      <input autocomplete="off" type="text" name="s" id="menu-search" placeholder="搜索..." data-root="" />
                  </div>
              </div>
          </div>
      </div>
  </div>
  </header>
        <div id="body" class="clearfix">
            <div class="container-fluid">
                <div class="row">
                    <div id="main" class="col-12 clearfix" role="main">
                        <article class="posti" itemscope itemtype="http://schema.org/BlogPosting">
                            <h1 class="post-title" itemprop="name headline">160CrackMe第十九Brad Soblesky.2</h1>
                            <div class="post-meta">
                                <p>
                                    Written by <a itemprop="name" href="/about.me.html" rel="author">Akkuman</a> with ♥ on <time datetime="1519998161" itemprop="datePublished"></time> in <a href="/tag/CrackMe/index.html">CrackMe </a><a href="/tag/%e9%80%86%e5%90%91/index.html">逆向 </a>
                                </p>
                            </div>
                            <div class="post-content" itemprop="articleBody">
                                <p><img src="" data-src="http://ww1.sinaimg.cn/large/c0264382gy1foyrcq7eydj207004jgli.jpg" alt="" /></p>

<p>查壳无壳，vc写的。</p>

<p>我们输入假码后，然后点击，弹出错误框，直接打开od，对<code>MessageBoxA</code>下断点也行，寻找字符串也行。</p>

<p>一般的错误提示部分代码类似于这样。</p>

<pre><code>    call xxx
    test xxx,xxx
    je xxxerror
    ...
    jmp xxx
    push xxx ;xxxerror
    ...

    call error
</code></pre>

<p>只需要往上找到关键跳直接nop就行。不过我们需要跟踪一下算法。</p>

<p>我们找到关键跳的<code>call</code>上方下断，可以看到他把一个东西压栈了，可以猜想是真码。</p>

<p><img src="" data-src="http://ww1.sinaimg.cn/large/c0264382gy1foyroy9x6yj20zm0g1ae2.jpg" alt="" /></p>

<p>然后我们测试一下111111和1643803416，提示正确，那我们找到这段的段首下断，然后f9运行程序重新输入假码点击Check。重点观察1643803416的出现地。</p>

<p><img src="" data-src="http://ww1.sinaimg.cn/large/c0264382gy1foyrt7stnaj20wx0ecdj6.jpg" alt="" /></p>

<p>我们可以看到在关键<code>call</code>的前方不远处就有出现，那么这个<code>add</code>前方的<code>call</code>是加密算法<code>call</code>吗？</p>

<p>显然不是的，我们可以看到这个<code>CString::Format</code>明显是对一个东西进行字符串格式化，格式是<code>%lu</code>(无符号长整数)，另外我们可以在它上面Enter跟一跟，可以发现直接从程序领空跳到系统领空了。所以我们可以猜测前面肯定是1643803416的一个什么数学形式然后用<code>%lu</code>格式化输出，我们可以推测是16进制，然后我们再重新来注意一下前面。</p>

<p>我们发现了1643803416的十六进制，在上方有个循环。其实之前在f8下来的时候，那个循环我们就可以推测是算法，现在经过分析可以更加肯定了。<code>mov eax,[local.4]</code>这个是这个循环最终跳出来的地方，那么<code>local.4</code>那里就是我们所需要找的东西。</p>

<p><img src="" data-src="http://ww1.sinaimg.cn/large/c0264382gy1foys1xvfuoj20rb0bwgnu.jpg" alt="" /></p>

<p>在我们之前的两边跟中，我们可以测试发现<code>local.7</code>是你输入的Name的长度，<code>local.5</code>是我们输入的名字。</p>

<p>我们把上面的循环好好跟一遍。下面直接看我注释理解吧。对了，我们跟踪过程中也可以发现Name长度不能小于5，就在这个循环上方有个简单的判断。</p>

<pre><code>004015BE  |&gt; \C745 E0 00000&gt;mov [local.8],0x0
004015C5  |.  EB 09         jmp short Brad_Sob.004015D0
004015C7  |&gt;  8B55 E0       /mov edx,[local.8]
004015CA  |.  83C2 01       |add edx,0x1
004015CD  |.  8955 E0       |mov [local.8],edx                       ;  local8第一次进入循环为0，后续循环每次+1
004015D0  |&gt;  8B45 E0        mov eax,[local.8]
004015D3  |.  3B45 E4       |cmp eax,[local.7]                       ;  local7 = len(name)
004015D6  |.  7D 42         |jge short Brad_Sob.0040161A             ;  当local8&gt;=len(name)跳出循环
004015D8  |.  8B4D E0       |mov ecx,[local.8]
004015DB  |.  51            |push ecx
004015DC  |.  8D4D EC       |lea ecx,[local.5]                       ;  local5=name
004015DF  |.  E8 1C030000   |call Brad_Sob.00401900                  ;  取name[local8]的十六进制ascii放入al
004015E4  |.  0FBED0        |movsx edx,al
004015E7  |.  8B45 F0       |mov eax,[local.4]                       ;  local4初始值为0x81276345
004015EA  |.  03C2          |add eax,edx
004015EC  |.  8945 F0       |mov [local.4],eax                       ;  local4 += name[local8]的十六进制
004015EF  |.  8B4D E0       |mov ecx,[local.8]
004015F2  |.  C1E1 08       |shl ecx,0x8
004015F5  |.  8B55 F0       |mov edx,[local.4]
004015F8  |.  33D1          |xor edx,ecx
004015FA  |.  8955 F0       |mov [local.4],edx                       ;  local4 = (local8&lt;&lt;8)^local4
004015FD  |.  8B45 E0       |mov eax,[local.8]
00401600  |.  83C0 01       |add eax,0x1
00401603  |.  8B4D E4       |mov ecx,[local.7]
00401606  |.  0FAF4D E0     |imul ecx,[local.8]
0040160A  |.  F7D1          |not ecx
0040160C  |.  0FAFC1        |imul eax,ecx                            ;  eax = (~(len(name)*local8))*(local8+1)
0040160F  |.  8B55 F0       |mov edx,[local.4]
00401612  |.  0FAFD0        |imul edx,eax
00401615  |.  8955 F0       |mov [local.4],edx                       ;  local4 *= eax
00401618  |.^ EB AD         \jmp short Brad_Sob.004015C7
0040161A  |&gt;  8B45 F0       mov eax,[local.4]

</code></pre>

<p>相信结合我的注释自己细看一遍应该不太费力。下面直接写注册算法。其实上面的基本上用伪代码都写的比较明白了。</p>

<pre><code class="language-c">#include &lt;stdio.h&gt;
#include &lt;string.h&gt;

int main()
{
	// name为输入的第一个值 
	char* name = &quot;111111&quot;;
	int len_name = strlen(name);
	
	if (len_name&lt;5)
		// name小于5出现提示并退出 
		printf(&quot;User Name must have at least 5 characters.\n&quot;);
	else
	{
		long result = 0x81276345;
		for(int i = 0; i &lt; len_name; i++)
		{
			result += name[i];
			result ^= (i&lt;&lt;8);
			result *= ~(len_name*i)*(i+1);
		}
		printf(&quot;result: %lu\n&quot;,result);
	}
	return 0;
}
</code></pre>

                            </div>
                            <div style="display:block;" class="clearfix">
                                <section style="float:left;">
                                    <span itemprop="keywords" class="tags">
                                        tag(s): <a href="/tag/CrackMe/index.html">CrackMe </a><a href="/tag/%e9%80%86%e5%90%91/index.html">逆向 </a>
                                    </span>
                                </section>
                                <section style="float:right;">
                                    <span><a id="btn-comments" href="javascript:isComments();">show comments</a></span> · <span><a href="javascript:goBack();">back</a></span> · 
                                    <span><a href="/">home</a></span>
                                </section>
                            </div>
                            



<div id="comments" class="gen">
    <script>
        document.write('<section id="disqus_thread"></section>');
        var site_comment_load = function disqus() {
            var d = document, s = d.createElement('script');
            s.src = '//Akkum4n.disqus.com/embed.js';
            s.setAttribute('data-timestamp', +new Date());
            (d.head || d.body).appendChild(s);
        }
    </script>
</div>

                        </article>
                    </div>
                </div>
            </div>
        </div>
        <footer id="footer" role="contentinfo">
    <div class="container-fluid">
        <div class="row">
        <div class="col-12">
            &copy; 
            <script type="text/javascript">
                document.write(new Date().getFullYear());
            </script>
            <a href="/">Akkuman</a>.
            Using <a target="_blank" href="http://www.chole.io/">Ink</a> & <a target="_blank" href="/">Story</a>.
        </div>
        </div>
    </div>
</footer>

<script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
<script src="/bundle/js/prism.js"></script>
<script src="/bundle/js/zoom-vanilla.min.js"></script>
<script src="/bundle/js/main.js"></script>

<script>
    window.onload=function(){
        if (window.location.hash!='') {
          var i=window.location.hash.indexOf('#comment');
          var ii=window.location.hash.indexOf('#respond-post');
          if (i != '-1' || ii != '-1') {
            document.getElementById('btn-comments').innerText='hide comments';
            document.getElementById('comments').style.display='block';
          }
        }
    }

    function isMenu(){
        if(document.getElementById('menu-1').style.display=='inline'||document.getElementById('menu-1').style.display=='block'){
            $('#search-box').fadeOut(200);
            $('#menu-page').fadeOut(200);
            $('#menu-1').fadeOut(500);
            $('#menu-2').fadeOut(400);
            $('#menu-3').fadeOut(300);
        } else {
            $('#menu-1').fadeIn(150);
            $('#menu-2').fadeIn(150);
            $('#menu-3').fadeIn(150);
        }
    }

    function isMenu1(){
        if(document.getElementById('menu-page').style.display=='block'){
            $('#menu-page').fadeOut(300);
        } else {
            $('#menu-page').fadeIn(300);
        }
    }

    function isMenu2(){
        if(document.getElementById('torTree')){
            if(document.getElementById('torTree').style.display=='block'){
                $('#torTree').fadeOut(300);
            } else {
                $('#torTree').fadeIn(300);
            }
        }
    }

    function isMenu3(){
        if(document.getElementById('search-box').style.display=='block'){
            $('#search-box').fadeOut(300);
        } else {
            $('#search-box').fadeIn(300);
        }
    }

    function isComments(){
        if(document.getElementById('btn-comments').innerText=='show comments'){
            document.getElementById('btn-comments').innerText='hide comments';
            document.getElementById('comments').style.display='block';
            site_comment_load();
        } else {
            document.getElementById('btn-comments').innerText='show comments';
            document.getElementById('comments').style.display='none';
        }
    }

    function Search404(){
        $('#menu-1').fadeIn(150);
        $('#menu-2').fadeIn(150);
        $('#menu-3').fadeIn(150);
        $('#search-box').fadeIn(300);
    }

    function goBack(){
        window.history.back();
    }
</script>


<script async>
"use strict";
(function(){
var cp = function(){
    var len = cPlayerOptions.length;
    for(var i=0;i<len;i++){
        var element = document.getElementById('player' + cPlayerOptions[i]['id'])
        while (element.hasChildNodes()) {
            element.removeChild(element.firstChild);
        };
        cPlayers[i] = new cPlayer({
            element: element,
            list: cPlayerOptions[i]['list'],
            });
    };
    cPlayers = [];cPlayerOptions = [];
};
var script = document.createElement('script');
script.type = "text/javascript";
script.src = "https://cdn.bootcss.com/cplayer/3.2.1/cplayer.js";
script.async = true;
if(script.readyState){  
    script.onreadystatechange = function(){
        if (script.readyState == "loaded" ||
            script.readyState == "complete"){
            script.onreadystatechange = null;
            cp();
        }
    };
}else{  
    script.onload = function(){
        cp();
    };
}
document.head.appendChild(script);
})();
</script>

    </body>
</html>
